Viper extends Vi with a number of useful features. This includes various search functions, histories of search strings, Ex commands, insertions, and Vi's destructive commands. In addition, Viper supports file name completion and history, completion of Ex commands and variables, and many other features. Some of these features are explained in detail elsewhere in this document. Other features are explained here.
(viper-buffer-search-enable)viper-buffer-search-char nilviper-buffer-search-enable sets
viper-buffer-search-char to g.
Alternatively, the user can set
viper-buffer-search-char in .viper to a key sequence to be used for
buffer search. There is no need to call
viper-buffer-search-enable in that case.
viper-toggle-search-styleHowever, we found that the most convenient way to toggle these options is to bind a Vi macro to bind // to toggles case sensitivity and to /// to toggles vanilla search. Thus, quickly hitting / twice will switch Viper from case sensitive search to case-insensitive. Repeating this once again will restore the original state. Likewise, quickly hitting / three times will switch you from vanilla-style search to search via regular expressions. If you hit something other than / after the first / or if the second / doesn't follow quickly enough, then Viper will issue the usual prompt / and will wait for input, as usual in Vi. If you don't like this behavior, you can “unrecord” these macros in your ~/.viper file. For instance, if you don't like the above feature, put this in ~/.viper:
(viper-set-searchstyle-toggling-macros 'undefine)
If you don't like this feature as a default, but would still like to have it in some major modes, you can do so by first unsetting it globally, as shown above, and then setting it in the desired major modes as follows:
(viper-set-searchstyle-toggling-macros nil 'c-mode)
(viper-set-searchstyle-toggling-macros nil 'lisp-mode)
Vi-isms in Emacs statedired-mode,
mh-folder-mode, Info-mode, and
Buffer-menu-mode (more may be added in the
future). So, in the above modes, Viper binds `/' so that it
will behave Vi-style. Furthermore, in those major modes,
Viper binds `:' to invoke ex-style commands, like in
vi-state. And, as described above, `//' and `///' get bound
to Vi-style macros that toggle case-insensitivity and
regexp-search.
If you don't like these features—which I don't
really understand—you can unbind `/' and `:' in
viper-dired-modifier-map (for Dired) or in
viper-slash-and-colon-map, for other modes.
To unbind the macros `//' and `///' for a major mode where
you feel they are undesirable, execute
viper-set-emacs-state-searchstyle-macros with a
non-nil argument. This can be done either
interactively, by supplying a prefix argument, or by
placing
(viper-set-emacs-state-searchstyle-macros 'undefine)
in the hook to the major mode (e.g.,
dired-mode-hook). See Vi Macros, for more
information on Vi macros.
viper-heading-startviper-heading-endM-x viper-set-expert-levelviper-smart-suffix-list '("" "tex" "c" "cc" "el"
"p")For instance, if completion stopped at `paper.' and the user typed <RET>, then Viper will check if the files `paper.', `paper.tex', `paper.c', etc., exist. It will take the first such file. If no file exists, Viper will give a chance to complete the file name by typing the appropriate suffix. If `paper.' was the intended file name, hitting return will accept it.
To turn this feature off, set the above variable to
nil.
viper-insertion-ring-size 14viper-insertion-ring-size. If you enter
Insert or Replace state you can reinsert strings from this
ring by typing C-c M-p or C-c M-n. The
former will search the ring in the direction of older
insertions, and the latter will search in the direction of
newer insertions. Hitting C-c M-p or C-c
M-n in succession will undo the previous insertion from
the ring and insert the next item on the ring. If a larger
ring size is needed, change the value of the above variable
in the ~/.viper file.
Since typing these sequences of keys may be tedious, it is suggested that the user should bind a function key, such as f31, as follows:
(define-key viper-insert-global-user-map [f31]
'viper-insert-prev-from-insertion-ring)
This binds f31 (which is usually R11
on a Sun workstation) to the function that inserts the
previous string in the insertion history. To rotate the
history in the opposite direction, you can either bind an
unused key to
viper-insert-next-from-insertion-ring or hit any
digit (1 to 9) then f31.
One should not bind the above functions to M-p
or M-n, since this will interfere with the
minibuffer histories and, possibly, other major
modes.
viper-command-ring-size 14
(define-key viper-vi-global-user-map [f31]
'viper-prev-destructive-command)
binds the key f31 (which is usually
R11 on a Sun workstation) to the function that
searches the command history in the direction of older
commands. To search in the opposite direction, you can either
bind an unused key to
viper-next-destructive-command or hit any digit
(1 to 9) then f31.
One should not bind the above functions to M-p
or M-n, since this will interfere with the
minibuffer histories and, possibly, other major
modes.
viper-minibuffer-vi-face
'viper-minibuffer-vi-faceviper-minibuffer-insert-face
'viper-minibuffer-insert-faceviper-minibuffer-emacs-face
'viper-minibuffer-emacs-faceViper is located in this widget under the Emulations customization subgroup of the Editing group. All Viper faces are grouped together in Viper's Highlighting customization subgroup.
Note that only the text you type in is affected by the above faces. Prompts and minibuffer messages are not affected.
Purists who do not like adornments in the minibuffer can always zap them by putting
(copy-face 'default 'viper-minibuffer-vi-face)
(copy-face 'default 'viper-minibuffer-insert-face)
(copy-face 'default 'viper-minibuffer-emacs-face)
in the ~/.viper
file or through the customization widget, as described above.
However, in that case, the user will not have any indication
of the current Viper state in the minibuffer. (This is
important if the user accidentally switches to another Viper
state by typing <ESC> or C-z).
M-x viper-go-awayM-x toggle-viper-modeViper provides some support for multi-file documents and programs. If a document consists of several files we can designate one of them as a master and put the following at the end of that file:
;; Local Variables:
;; eval: (viper-setup-master-buffer "file1" "file2" "file3" "file4")
;; End:
where file1 to
file4 are names of files related to the master file.
Next time, when the master file is visited, the command
viper-setup-master-buffer will be evaluated and the
above files will be associated with the master file. Then, the
new Ex command :RelatedFile (abbr. :R) will
display files 1 to 4 one after another, so you can edit them. If
a file is not in any Emacs buffer, it will be visited. The
command PreviousRelatedFile (abbr., :P)
goes through the file list in the opposite direction.
These commands are akin to :n and :N, but
they allow the user to focus on relevant files only.
Note that only the master file needs to have the aforementioned block of commands. Also, ";;" above can be replaced by some other markers. Semicolon is good for Lisp programs, since it is considered a comment designator there. For LaTeX, this could be "%%%", and for C the above block should be commented out.
Even though these commands are sometimes useful, they are no substitute for the powerful tag table facility of Emacs. Viper's :tag command in a primitive interface to Emacs tags. See Tags, for more information on tags.
The following two commands are normally bound to a mouse click
and are part of Viper. They work only if Emacs runs as an
application under X Windows (or under some other window system
for which a port of GNU Emacs 20 is available). Clicking the
mouse when Emacs is invoked in an Xterm window (using emacs
-nw) will do no good.
viper-mouse-search-key (meta shift 1)Note: while loading initially, Viper binds this mouse
action only if it is not already bound to something else. If
you want to use the mouse-search feature, and the
Meta-Shift-Mouse-1 mouse action is already bound
to something else, you can rebind the mouse-search feature by
setting viper-mouse-search-key to something else
in your ~/.viper file:
(setq viper-mouse-search-key '(meta 1))
This would bind mouse search to the action invoked by
pressing the Meta key and clicking mouse button 1. The
allowed values of viper-mouse-search-key are
lists that contain a mouse-button number (1,2, or 3) and any
combination of the words `control', `meta', and `shift'.
If the requested mouse action (e.g., (meta 1)) is already
taken for other purposes then you have to confirm your
intention by placing the following command in
~/.viper after setting
viper-mouse-search-key:
(viper-bind-mouse-search-key 'force)
You can also change this setting interactively, through the customization widget of Emacs (type :customize).
The region that is chosen as a pattern to search for is determined as follows. If search is invoked via a single click, Viper chooses the region that lies between the beginning of the “word” under the pointer (“word” is understood in Vi sense) and the end of that word. The only difference with Vi's words is that in Lisp major modes `-' is considered an alphanumeric symbol. This is done for the convenience of working with Lisp symbols, which often have an `-' in them. Also, if you click on a non-alphanumeric character that is not a word separator (in Vi sense) then this character will also be considered alphanumeric, provided that it is adjacent (from either side) to an alphanumeric character. This useful feature gives added control over the patterns selected by the mouse click.
On a double-click, the region is determined by the beginning of the current Vi's “Word” (i.e., the largest non-separator chunk of text) and the End of that “Word” (as determined by the E command).
On a triple-click, the region consists of the entire line where the click occurred with all leading and trailing spaces and tabs removed.
viper-mouse-insert-key (meta shift 2)Note: while loading initially, Viper binds this mouse
action only if it not already bound to something else. If you
want to use this feature and the default mouse action is
already bound, you can rebind mouse-insert by placing this
command in ~/.viper:
(setq viper-mouse-insert-key '(meta 2))
If you want to bind mouse-insert to an action even if this
action is already taken for other purposes in Emacs, then you
should add this command to ~/.viper, after
setting viper-mouse-insert-key:
(viper-bind-mouse-insert-key 'force)
This value can also be changed via the Emacs customization
widget at the menubar.
viper-multiclick-timeoutdouble-click-time in Emacs
and to mouse-track-multi-click-time milliseconds
in XEmacs.If you decide that you don't like the above feature and always
want search/insertion be performed in the frame where the click
occurs, don't bind (and unbind, if necessary)
viper-mouse-catch-frame-switch from the mouse event
it is bound to.
Mouse search is integrated with Vi-style search, so you can
repeat it with n and N. It should be also
noted that, while case-sensitivity of search in Viper is
controlled by the variable viper-case-fold-search,
the case of mouse search is controlled by the Emacs variable
case-fold-search, which may be set differently from
viper-case-fold-search. Therefore, case-sensitivity
of mouse search may be different from that of the usual Vi-style
search.
Finally, if the way Viper determines the word to be searched
for or to be inserted is not what you want, there is a variable,
viper-surrounding-word-function, which can be
changed to indicate another function for snarfing words out of
the buffer. The catch is that you will then have to write such a
function and make it known to your Emacs. The function
viper-surrounding-word in viper.el can be used as a guiding
example.